/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

import { expect } from '@jest/globals';
import { parseJsonText } from '@ohos/hvigor';
import * as fse from 'fs-extra';
import { readFileSync } from 'fs-extra';
import * as path from 'path';
import { resolve } from 'path';

import { CompileModeEnum } from '../../src/enum/compile-mode-enum';
import { ModuleBuildProfile } from '../../src/options/build/module-build-profile';

import {
  initByStageEmptyApp,
  initByStageEmptyService,
  initExecuteCommand,
  ohosUnsupportService,
  runHvigor,
} from './common/common';
import { ModuleBuildProfileModifier } from './common/modifier/module-build-profile-modifier';
import { Probes } from './common/probes';
import ModuleBuildOpt = ModuleBuildProfile.ModuleBuildOpt;


describe('test process profile Incremental', () => {
  test.concurrent('test stage app', async () => {
    await initByStageEmptyApp(testProcessProfile);
  });

  test.concurrent('test stage Service', async () => {
    await initByStageEmptyService(testProcessProfile);
  });
});

async function testProcessProfile(projectRoot: string) {
  const commands = initExecuteCommand({
    mode: 'module',
    module: 'entry',
    product: 'default',
    tasks: 'default@ProcessProfile'
  });

  ohosUnsupportService(projectRoot, commands, 'entry');
  new ModuleBuildProfileModifier(projectRoot, 'entry').updateTargetRuntimeOS('default', 'HarmonyOS');
  new ModuleBuildProfileModifier(projectRoot, 'feature').updateTargetRuntimeOS('default', 'HarmonyOS');
  new ModuleBuildProfileModifier(projectRoot, 'slibrary').updateTargetRuntimeOS('default', 'HarmonyOS');

  // 第一次执行任务
  const result1 = runHvigor(projectRoot, commands);
  expect(result1.exitCode).toEqual(0);
  expect(result1.stdout.includes('BUILD SUCCESSFUL')).toBeTruthy();
  expect(result1.stdout.includes('Finished :entry:default@ProcessProfile')).toBeTruthy();

  // ark标识要带上版本号
  const probe = new Probes(projectRoot, resolve(projectRoot, 'entry'));
  expect(readFileSync(probe.getIntermediatesProcessProfile()).toString()).toMatch(/ark\d.\d.\d.\d/);

  // 没有修改，第二次执行任务
  const result2 = runHvigor(projectRoot, commands, { stderr: 'pipe' });
  expect(result2.exitCode).toEqual(0);
  expect(result2.stdout.includes('BUILD SUCCESSFUL')).toBeTruthy();
  expect(result2.stdout.includes('UP-TO-DATE :entry:default@ProcessProfile')).toBeTruthy();

  // 修改module.json5，第三次执行任务
  const entryBuildJsonPath = path.resolve(projectRoot, 'entry', 'build-profile.json5');
  const entryBuildJson = parseJsonText(fse.readFileSync(entryBuildJsonPath).toString()) as ModuleBuildOpt;
  if (entryBuildJson.targets && entryBuildJson.targets.length > 0) {
    if (entryBuildJson.targets[0].config) {
      if (entryBuildJson.targets[0].config.deviceType) {
        entryBuildJson.targets[0].config.deviceType.push('tablet');
      } else {
        entryBuildJson.targets[0].config.deviceType = ['tablet'];
      }
    } else {
      entryBuildJson.targets[0].config = { deviceType: ['tablet'] };
    }
  }
  fse.writeFileSync(entryBuildJsonPath, JSON.stringify(entryBuildJson));
  const result3 = runHvigor(projectRoot, commands, { stderr: 'pipe' });
  expect(result3.exitCode).toEqual(0);
  expect(result3.stdout.includes('BUILD SUCCESSFUL')).toBeTruthy();
  expect(result3.stdout.includes('Finished :entry:default@ProcessProfile')).toBeTruthy();

  // 没有修改，第四次执行任务
  const result4 = runHvigor(projectRoot, commands, { stderr: 'pipe' });
  expect(result4.exitCode).toEqual(0);
  expect(result4.stdout.includes('BUILD SUCCESSFUL')).toBeTruthy();
  expect(result4.stdout.includes('UP-TO-DATE :entry:default@ProcessProfile')).toBeTruthy();

  // 修改compileMode，第五次执行任务，现在compileMode应不影响增量判断
  if (entryBuildJson.buildOption) {
    entryBuildJson.buildOption.compileMode = CompileModeEnum.JS_BUNDLE;
  }
  fse.writeFileSync(entryBuildJsonPath, JSON.stringify(entryBuildJson));
  const result5 = runHvigor(projectRoot, commands, { stderr: 'pipe' });
  expect(result5.exitCode).toEqual(0);
  expect(result5.stdout.includes('BUILD SUCCESSFUL')).toBeTruthy();
  expect(result5.stdout.includes('UP-TO-DATE :entry:default@ProcessProfile')).toBeTruthy();

  // 修改buildRoot，影响前置任务MergeProfile重新执行，第6次执行任务
  commands.push('-p');
  commands.push('buildRoot=build1');
  const result6 = runHvigor(projectRoot, commands, { stderr: 'pipe' });
  expect(result6.exitCode).toEqual(0);
  expect(result6.stdout.includes('BUILD SUCCESSFUL')).toBeTruthy();
  expect(result6.stdout.includes('Finished :entry:default@ProcessProfile')).toBeTruthy();

  // 没有修改，第8次执行任务
  const result7 = runHvigor(projectRoot, commands, { stderr: 'pipe' });
  expect(result7.exitCode).toEqual(0);
  expect(result7.stdout.includes('BUILD SUCCESSFUL')).toBeTruthy();
  expect(result7.stdout.includes('UP-TO-DATE :entry:default@ProcessProfile')).toBeTruthy();
}
